#ifndef PLAYER_H
#define PLAYER_H

#include "WindowsCompatibility/Physx.h"
#include <string>
#include "WrappedContainers/ArrayList.h"
#include "Entities/ActorEntities/Cannon.h"
#include "Entities/ActorEntities/Building.h"
#include "Util/Direction2D.h"
#include "SurfaceRenderingData.h"

class Cannon;
class Building;

class Player {
public:
	enum PLACEABLE {
		PL_TOWER,
		PL_WALL_FRONT,
		PL_WALL_SIDE,
		PL_HOUSE
	};

protected:
	std::string name;
	float placementSlotX;
	float placementSlotZ;
	int selectedCannonIndex;
	float selectionAnimationValue;
	int gold;
	bool explosiveCannonBallsSelected;
	bool placementAllowed;
	bool buildMode;
	PLACEABLE selectedPlaceable;
	NxVec3 placementBoxRenderPosition;
	int turnsMade;

	static SurfaceRenderingData srdPlacementAllowed;
	static SurfaceRenderingData srdPlacementNotAllowed;
	static SurfaceRenderingData srdCannonSelection;

public:
	ArrayList<Cannon*> cannons;
	ArrayList<Building*> buildings;

	int areaCenterX;

protected:
	void KeepPlacementBoxInArea();

public:
	static void Load();

	static std::string GetNameOfPlacable(PLACEABLE v);

	Player();
	virtual ~Player();

	void Reset();

	inline const std::string& GetName() const { return name; }
	inline void SetName(const std::string& name) { this->name = name; }

	void SetSelectedCannonIndex(int index);
	int GetSelectedCannonIndex() const;
	Cannon* GetSelectedCannon() const;
	void SelectNextCannon();

	int GetBuildingsCount() const;
	void PlaceHouses();

	inline void EndTurn() { ++turnsMade; }
	inline int GetTurnsMade() { return turnsMade; }

	inline void SetPlacementSlot(int x, int z) { placementSlotX = x; placementSlotZ = z; };
	inline int GetPlacementSlotX() const { return placementSlotX; }
	inline int GetPlacementSlotZ() const { return placementSlotZ; }
	inline bool IsPlacementAllowed() const { return placementAllowed; }
	void MovePlacementSlot(DIRECTION_2D direction);
	void MovePlacementSlot(const NxVec3& v);
	void CheckPlacementAllowed();
	inline const NxVec3& GetPlacementBoxRenderPosition() const { return placementBoxRenderPosition; }
	NxVec3 GetPlacementBoxPosition() const;
	NxVec3 GetPlacementBoxDimension() const;

	void PlaceSelectedPlaceable();

	inline int GetGold() const { return gold; }
	inline void AddGold(int gold) { this->gold += gold; }
	inline void TakeGold(int gold) { this->gold -= gold; }
	int GetCosts(PLACEABLE v) const;

	inline bool GetExplosiveCannonBallsSelected() const { return explosiveCannonBallsSelected; }
	void SetExplosiveCannonBallsSelected(bool b);

	void Draw();
	void Tick(float elapsedTime);

	void ToggleBuildMode();
	inline bool IsInBuildMode() const { return buildMode; }

	void SetPlaceable(PLACEABLE v, bool message = true);
	inline PLACEABLE GetSelectedPlaceable() const { return selectedPlaceable; }

	static inline int GetStartGold() { return 5000; }
};

#endif //PLAYER_H
